package com.ktjy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktjy.dto.ClueDTO;
import com.ktjy.dto.LoginUser;
import com.ktjy.mapper.*;
import com.ktjy.pojo.*;
import com.ktjy.service.ITbClueService;
import com.ktjy.utils.Constants;
import com.ktjy.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * <p>
 * 线索 服务实现类
 * </p>
 *
 * @author jjx
 * @since 2025-08-19
 */
@Service
public class TbClueServiceImpl extends ServiceImpl<TbClueMapper, TbClue> implements ITbClueService {
    @Autowired
    TbClueMapper clueMapper;
    @Autowired
    TbAssignRecordMapper assignRecordMapper;
    @Autowired
    TbRulePoolMapper rulePoolMapper;
    @Autowired
    TbClueTrackRecordMapper clueTrackRecordMapper;
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    TbBusinessMapper businessMapper;
    @Autowired
    TbActivityMapper activityMapper;

    @Override
    public IPage<TbClue> findPage(ClueDTO clueDTO, Integer pageNo, Integer pageSize) {
        //构造分页条件
        Page page=new Page(pageNo,pageSize);
        return clueMapper.getPage(page,clueDTO);
    }

    @Override
    @Transactional
    public void saveClue(TbClue tbClue) {
        LoginUser loginUser=(LoginUser)SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        //1. 保存线索信息
        //1.1 查询线索池规则
        QueryWrapper qw=new QueryWrapper();
        qw.eq("type",Constants.RULE_TYPE_CLUE);
        TbRulePool rulePool = rulePoolMapper.selectOne(qw);
        //指定线索的失效时间
        LocalDateTime endTime= DateUtil.getDate(rulePool.getLimitTime(),rulePool.getLimitTimeType(),
                LocalDateTime.now());
        tbClue.setEndTime(endTime);
        this.save(tbClue);
        //2. 保存线索分配信息
        TbAssignRecord assignRecord = new TbAssignRecord();
        assignRecord.setAssignId(tbClue.getId());
        assignRecord.setUserId(loginUser.getUserId());
        assignRecord.setUserName(loginUser.getUsername());
        assignRecord.setDeptId(loginUser.getDeptId());
        assignRecord.setType(Constants.RULE_TYPE_CLUE);
        assignRecordMapper.insert(assignRecord);
    }

    @Override
    @Transactional
    public void assignClue(Long clueId, Long userId) {
        //1. 查询线索池规则
        QueryWrapper qw=new QueryWrapper();
        qw.eq("type",Constants.RULE_TYPE_CLUE);
        TbRulePool rulePool = rulePoolMapper.selectOne(qw);
        // 2. 统计当前分配人手头拥有的线索数(线索状态为待跟进和跟进中的)
        int count = assignRecordMapper.countAssignClueByUserId(userId);
        if (count >= rulePool.getMaxNunmber()) {
            throw new RuntimeException("分配失败！系统规则: 线索最大保有量(" + rulePool.getMaxNunmber() + ")，剩余可以分配" + (rulePool.getMaxNunmber() - count) + "条线索");
        }
        // 3. 线索重新分配
        // 修改线索的状态为已分配，待跟进，
        // 失效时间为当前分配时间+失效时间,
        // 清空下次跟踪时间
        UpdateWrapper uw=new UpdateWrapper();
        uw.eq("id",clueId);
        uw.set("status",Constants.RULE_TYPE_BUSINESS);
        LocalDateTime endTime= DateUtil.getDate(rulePool.getLimitTime(),rulePool.getLimitTimeType(),
                LocalDateTime.now());
        uw.set("end_time",endTime);
        uw.set("next_time",null);
        this.update(uw);
        //4. 新增线索分配记录
        // 4.1 保留上一条分配记录(修改上一条分配记录为非最新分配记录)
        uw=new UpdateWrapper();
        uw.eq("assign_id",clueId);
        uw.eq("type",Constants.RULE_TYPE_CLUE);
        uw.set("latest","0");
        assignRecordMapper.update(uw);
        // 4.2. 新建分配记录
        TbAssignRecord assignRecord = new TbAssignRecord();
        assignRecord.setAssignId(clueId);
        assignRecord.setUserId(userId);
        SysUser sysUser = sysUserMapper.selectById(userId);
        assignRecord.setUserName(sysUser.getUserName());
        assignRecord.setDeptId(sysUser.getDeptId());
        assignRecord.setType(Constants.RULE_TYPE_CLUE);
        assignRecordMapper.insert(assignRecord);
    }

    @Override
    @Transactional
    public void falseClue(Long clueId, String reason, String record) {
        //1.查询线索
        TbClue clue = clueMapper.selectById(clueId);
        int falseCount = clue.getFalseCount();
        //2.上报超过三次删除
        if (falseCount >= 2) {
            // 删除这条线索
            clueMapper.deleteById(clueId);
            return;
        }
        //3.少于三次入线索池
        UpdateWrapper uw=new UpdateWrapper();
        uw.eq("id",clueId);
        uw.set("status",Constants.FALSE);
        uw.set("false_count",clue.getFalseCount() + 1);
        uw.set("next_time",null);
        this.update(uw);
        // 4.保存线索跟进记录
        TbClueTrackRecord trackRecord = new TbClueTrackRecord();
        trackRecord.setClueId(clueId);
        trackRecord.setType(Constants.CLUE_TRACK_RECORD_TYPE_1);
        trackRecord.setFalseReason(reason);
        trackRecord.setRecord(record);
        clueTrackRecordMapper.insert(trackRecord);
    }

    @Override
    public void gainClue(Long clueId, Long userId){
        //1. 查询线索池规则
        QueryWrapper qw=new QueryWrapper();
        qw.eq("type",Constants.RULE_TYPE_CLUE);
        TbRulePool rulePool = rulePoolMapper.selectOne(qw);
        // 2. 统计当前分配人手头拥有的线索数(线索正在跟进还未结束的线索)
        int count = assignRecordMapper.countAssignClueByUserId(userId);
        if (count >= rulePool.getMaxNunmber()) {
            throw new RuntimeException("分配失败！系统规则: 线索最大保有量(" + rulePool.getMaxNunmber() + ")，剩余可以分配" + (rulePool.getMaxNunmber() - count) + "条线索");
        }
        // 3.最近捞取记录
        qw=new QueryWrapper();
        qw.eq("assign_id",clueId);
        qw.eq("type",Constants.RULE_TYPE_CLUE);
        qw.eq("latest","1");
        TbAssignRecord assignRecord = assignRecordMapper.selectOne(qw);
        //如果该条线索最近分配人是当前分配人
        if (assignRecord != null && assignRecord.getUserId().equals(userId)) {
            //计算可以重复捞取的时间过了没
            LocalDateTime repeatGetTime = DateUtil.getDate(rulePool.getRepeatGetTime(),
                    rulePool.getRepeatType(),assignRecord.getCreateTime());
            // 捞取限制时间内，不让捞取
            if (LocalDateTime.now().isBefore(repeatGetTime)) {
                throw new RuntimeException("捞取失败！需要在 " + repeatGetTime + " 后捞取");
            }
        }
        //4. 捞取成功重新分配
        UpdateWrapper uw=new UpdateWrapper();
        uw.eq("id",clueId);
        uw.set("status",Constants.UNFOLLOWED);
        LocalDateTime endTime= DateUtil.getDate(rulePool.getLimitTime(),rulePool.getLimitTimeType(),
                LocalDateTime.now());
        uw.set("end_time",endTime);
        uw.set("next_time",null);
        this.update(uw);
        //4. 新增线索分配记录
        // 4.1 保留上一条分配记录(修改上一条分配记录为非最新分配记录)
        uw=new UpdateWrapper();
        uw.eq("assign_id",clueId);
        uw.eq("type",Constants.RULE_TYPE_CLUE);
        uw.set("latest","0");
        assignRecordMapper.update(uw);
        // 4.2. 新建分配记录
        assignRecord = new TbAssignRecord();
        assignRecord.setAssignId(clueId);
        assignRecord.setUserId(userId);
        SysUser sysUser = sysUserMapper.selectById(userId);
        assignRecord.setUserName(sysUser.getUserName());
        assignRecord.setDeptId(sysUser.getDeptId());
        assignRecord.setType(Constants.RULE_TYPE_CLUE);
        assignRecordMapper.insert(assignRecord);
    }

    @Override
    public TbClue getClueById(Long clueId) {
        TbClue clue = this.getById(clueId);
        if (clue != null && clue.getActivityId() != null) {
            TbActivity activity = activityMapper.selectById(clue.getActivityId());
            if (activity != null) {
                clue.setActivityInfo(activity.getCode() + ":" + activity.getName() + ":" + activity.getInfo());
            }
        }
        // 查询专派遣信息
        QueryWrapper qw=new QueryWrapper();
        qw.eq("assign_id",clueId);
        qw.eq("type",Constants.RULE_TYPE_CLUE);
        qw.eq("latest","1");
        TbAssignRecord assignRecord = assignRecordMapper.selectOne(qw);
        //证明是待分配数据
        if(assignRecord==null){
            return clue;
        }
        clue.setOwnerName(assignRecord.getUserName());
        clue.setOwnerTime(assignRecord.getCreateTime());
        return clue;
    }
}
